<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\api\controller;

use app\api\model\wxapp\Setting as WxappSettingModel;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\PayType as OrderPayTypeEnum;
use app\common\library\helper;
use app\common\exception\BaseException;
use app\common\library\wechat\WxSendGood;
use app\common\service\bangdou\Common as CommonService;
use app\common\service\Message as MessageService;
use app\common\service\XinLian\Tool;
use app\common\model\OrderCallbackLog as OrderCallbackLogModel;
use app\api\model\Order as OrderModel;
use app\common\service\bangdou\BdPay;


/**
 * 三券支付订单回调
 * Class PayNotice
 * @package app\api\controller
 */
class PayNotice extends Controller
{
    // 订单模型
    private $modelClass = [
        OrderTypeEnum::ORDER    => \app\api\service\order\PaySuccess::class,
        OrderTypeEnum::RECHARGE => \app\api\service\recharge\PaySuccess::class,
    ];

    /**
     * 支付成功异步通知
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function bangnuoNotice()
    {
        $data     = $this->request->param();
        $log_file = runtime_root_path() . 'api/log/bd_wx_pay_' . date('y-m-d') . '.log';
        file_put_contents($log_file, print_r($data, true) . "\n", FILE_APPEND);
        $message = CommonService::checkSign($data);
        if (isset($message['code']) && $message['code'] == 2) {
            return $this->renderError($message['message'] ?: '订单回调失败');
        }

        $attach = helper::jsonEncode(['order_type' => OrderTypeEnum::ORDER]);//商城订单
        // 实例化订单模型
        $model = $this->getOrderModel($data['out_trade_no'], $attach);
        // 订单信息
        $order = $model->getOrderInfo();
        empty($order) && $this->renderError('订单不存在');
        $data['good_type'] = $order['good_type'];
        // 订单支付成功业务处理
        $status = $model->onPaySuccess(OrderPayTypeEnum::WECHAT, $data);
        if ($status == false) {
            $this->renderError('数据更新失败');
        }
        if ($order['good_type'] == 'virtual_good') {//虚拟商品支付
            $pay_data['recharge_account'] = $order['goods'][0]['recharge_account'];
            $pay_data['goods_no'] = $order['goods'][0]['goods_no'];
            $pay_data['order_no'] = $order['order_no'];
            BdPay::OrderXinLianPayment($pay_data);
        }
        // 返回状态
        return $this->renderSuccess('回调成功');
    }

    /**
     * 实例化订单模型 (根据attach判断)
     * @param $orderNo
     * @param null $attach
     * @return mixed
     */
    private function getOrderModel($orderNo, $attach = null)
    {
        $attach = helper::jsonDecode($attach);
        // 判断订单类型返回对应的订单模型
        $model = $this->modelClass[$attach['order_type']];
        return new $model($orderNo);
    }

    /**
     * 支付成功异步通知
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function xinLianNotice()
    {
        $data = $this->request->param();
        if(empty($data)){
            return $this->renderError('参数不能为空');
        }
        $log_file = runtime_root_path() .'api/log/xinlian/callback_'.date('y-m-d').'.log';
        file_put_contents($log_file, print_r($data, true)."\n", FILE_APPEND);
        $sign = Tool::createSign($data, '0bb0637a3beb280dd78cb8c55ca8faf8');
        if ($data['sign'] != $sign) {
            return $this->renderError('sign不一致，订单回调失败');
        }
        $OrderCallbackLogModel = new OrderCallbackLogModel();
        $info                  = $OrderCallbackLogModel->where(['order_no' => $data['merchant_no'], 'merchant_no' => $data['order_no']])->find();
        $info['complete_time'] = $data['complete_time'];//紧跟$info之后
        $data['complete_time'] = strtotime($data['complete_time']);
        if (empty($info)) {
            $data['create_time'] = strtotime($data['create_time']);
            OrderCallbackLogModel::add('xinlian', $data);
            return $this->renderSuccess('回调成功');
        }
        if($info['recharge_status'] > 0){
            return $this->renderSuccess('回调成功');
        }

        // 整理订单信息
        $order = [
            'recharge_status'  => $data['recharge_status'],
            'complete_time'    => $data['complete_time'],
            'settlement_price' => $data['settlement_price'],
            'total_amount'     => $data['total_amount'],
            'actual_amount'    => $data['actual_amount'],
        ];
        // 更新订单状态
        $OrderCallbackLogModel->updateBase($order, ['order_no' => $data['merchant_no'],'merchant_no' => $data['order_no']]);
        $orderModel = new OrderModel();
        $info['good_type'] = 'virtual_good';
        if ($data['recharge_status'] == 3) { //充值成功，订单状态改成已完成
            //微信发货
            $Wxapp      = WxappSettingModel::getWxappConfig($info['store_id']);
            $WxSendGood = new WxSendGood($Wxapp);
            $WxSendGood->sendWechatOrderSelfPickup($info);
            //修改订单状态
            $orderModel->onBatchUpdate([$info['order_id']], [
                'receipt_status' => 20,//已收货
                'receipt_time'   => time(),
                'order_status'   => 30 //已完成
            ]);
            //小程序发订阅消息
            MessageService::VirtualGoodMessageNotice('order.messagewx', $info->toArray());
        }
        if ($data['recharge_status'] == 4) { //充值失败，退款原路返回
            $orderModel->OrderCancelByOrderId($info['order_id']);
            $info['refund_reason'] = '会员充值失败';
            MessageService::WxMessageOrderRefund('order.messagewx', $info->toArray());
        }
        // 返回状态
        return $this->renderSuccess('回调成功');
    }
}